import datetime
import logging

from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
from django.shortcuts import render, get_object_or_404
from django.utils.decorators import method_decorator
from django.views import View
from django.views.generic import TemplateView

from custom import UnBindRouteView, check_role
from system.models import Router, Server, OperationDetail
from utils.common.common import get_mac_status, change_route_status
from utils.common.db_handle import get_mac_info, structure_route
from utils.common.request_handle import RouteBind, RouteUnBind, RouteSend, RouteDetail
from utils.common.tools import query_params

logger = logging.getLogger(__name__)


@method_decorator(login_required, name='get')
@method_decorator(check_role, name='get')
class RouteView(TemplateView):
    """路由器列表视图"""

    template_name = 'system/route.html'


@method_decorator(login_required, name='get')
class RouteListView(View):
    """路由器列表页数据"""

    def get(self, request):
        ret = {'code': 0, 'msg': 'success', 'count': 0, 'data': []}
        user = request.user
        name = request.GET.get('mac_name')
        mac_addr = request.GET.get('mac_addr')
        server_addr = request.GET.get('server')

        page = int(request.GET.get('page', 1))
        limit = int(request.GET.get('limit', 10))
        start, end = (page - 1) * limit, page * limit  # 计算要查询的数据数量

        # 计算要查询的条件
        query_conditions = {'name__contains': name, 'mac_addr__contains': mac_addr,
                            'server_addr__contains': server_addr}
        params = query_params(
            query_conditions)  # {'name': '1586515834', 'mac_addr': '', 'server_addr': 'raccess1.vpn.cn'}

        if not params:
            # 查询用户的全部路由器（10条）
            route_obj = Router.get_route(user.id, start, end)
        else:
            # 前端按条件查询
            route_obj = Router.get_route_filter(user.id, params, start, end)

        mac_hmac_dict = Router.get_mac_hmac_dict(route_obj)  # 查询 hmac

        # 发送请求，获取路由状态
        results = get_mac_status(mac_hmac_dict, user)

        # print('results', results)

        # 获取用户的所有路由器信息
        route_list = structure_route(route_obj)
        data = change_route_status(route_list, results)  # 转换状态

        ret['count'] = len(route_list)
        ret['data'] = data

        return JsonResponse(ret)


@method_decorator(login_required, name='get')
class RouteBindView(View):
    """路由器绑定页面，点击绑定弹窗"""

    def get(self, request):
        macaddr = request.GET.get('mac')

        server_list = Server.get_all()
        tunnel_list = ['TCP']
        ret = {
            'macaddr': macaddr,
            'server_list': server_list,
            'tunnel_list': tunnel_list
        }

        return render(request, 'system/route_bind.html', ret)


class RouteUpdateView(View):
    """绑定和解绑服务器"""

    @method_decorator(login_required)
    def get(self, request):
        """解绑服务器"""
        mac_addr = request.GET.get('mac_addr')
        route_obj = Router.get_mac(mac_addr).first()

        result = UnBindRouteView().unbind(request, route_obj)
        print(result)

        return JsonResponse(result)

    @method_decorator(login_required)
    def post(self, request):
        """绑定服务器"""
        ret = {'code': 0, 'msg': 'success'}
        mac_addr = request.POST.get('mac_addr')
        server_addr = request.POST.get('server')
        tunnel = request.POST.get('tunnel')

        route_obj = Router.get_mac(mac_addr)[0]
        hmac = route_obj.hmac_addr
        bind_time = datetime.datetime.now()

        # print(mac_addr, server_addr, tunnel, server_addr == route_obj.server_addr)

        # 检查参数是否完整
        if not all([mac_addr, server_addr, tunnel]):
            ret = {'code': 10012, 'msg': '不能为空'}
            return JsonResponse(ret)

        # 是否已绑定服务器
        if route_obj.server_addr == server_addr:
            ret = {'code': 10013, 'msg': '不能重复绑定'}
            return JsonResponse(ret)

        # 开始绑定服务器
        rb = RouteBind()
        result = rb.route_bind(mac_addr, hmac, server_addr, tunnel)  # 绑定
        if result.get('code') == 0:
            # 绑定成功，更新数据库
            update_params = {
                'server_addr': server_addr,
                'tunnel': Router.get_tunnel_status(tunnel),
                'bind_time': bind_time,
            }
            Router.objects.filter(mac_addr=mac_addr).update(**update_params)  # 更新数据库
            OperationDetail.objects.create(result="{}绑定成功".format(mac_addr), user=request.user)  # 记录操作记录
            ret = result
        else:
            # 绑定失败
            ret['code'] = 10009
            ret['msg'] = '绑定失败'
            OperationDetail.objects.create(status=1, result="{}绑定失败".format(mac_addr), user=request.user)  # 记录操作记录

        print('绑定状态：', result)

        return JsonResponse(ret)


@method_decorator(login_required, name='get')
class RouteDeleteView(View):
    """删除路由设备"""

    def get(self, request):
        try:
            mac_addr = request.GET.get('mac_addr')
            route_obj = Router.get_mac(mac_addr).first()

            # 解绑
            UnBindRouteView().unbind(request, route_obj)

            # 删除数据库中路由设备
            Router.objects.filter(mac_addr=mac_addr).delete()
            OperationDetail.objects.create(operation_type=2, result="{} 删除成功".format(mac_addr),
                                           user=request.user)  # 记录操作记录

            ret = {'code': 0, 'msg': '删除成功'}
        except Exception as e:
            logger.error('删除路由设备错误：%s', e)
            ret = {'code': 10008, 'msg': '删除失败'}
            OperationDetail.objects.create(operation_type=2, status=1, result="删除失败", user=request.user)  # 记录操作记录

        return JsonResponse(ret)


@method_decorator(login_required, name='get')
class RouteStatusView(View):
    """轮询检查路由设备是否在线"""

    def get(self, request):
        user = request.user

        # 获取该用户的所有路由信息
        route_obj = Router.get_route(user.id)
        mac_hmac_dict = Router.get_mac_hmac_dict(route_obj)  # 返回用户的所有路由器Mac、hamc 地址字典

        # 发送请求，获取路由状态
        results = get_mac_status(mac_hmac_dict, user)

        return JsonResponse(results)


@method_decorator(login_required, name='get')
class RouteNameUpdateView(View):
    """修改路由器名称"""

    def get(self, request):
        ret = {'code': 0, 'msg': '修改成功'}
        route_name = request.GET.get('name')
        mac_addr = request.GET.get('mac_addr')
        route_new_name = request.GET.get('new_name')

        # 是否为空
        if not route_new_name:
            ret['code'] = 10012
            ret['msg'] = '名字不能为空'
            return JsonResponse(ret)

        # 名字是否一致
        if route_name == route_new_name:
            ret['code'] = 10026
            ret['msg'] = '不能修改为相同名称'
            return JsonResponse(ret)

        # 名字长度
        if (len(route_new_name) >= 15) and (len(route_new_name) < 5):
            ret['code'] = 10027
            ret['msg'] = '名称长度 5-15个字符'
            return JsonResponse(ret)

        Router.objects.filter(mac_addr=mac_addr).update(**{'name': route_new_name})

        return JsonResponse(ret)


@method_decorator(login_required, name='get')
class RouteDetailView(View):
    """路由器详情"""

    def get(self, request):
        mac_addr = request.GET.get('mac_addr')
        mac_status = request.GET.get('status')  # 路由器状态
        flag = request.GET.get('flag')

        route = get_object_or_404(Router, mac_addr=mac_addr)
        hmac_addr = route.hmac_addr
        payload = {"macaddr": ["%s" % mac_addr]}

        # 获取路由器详情
        res = RouteDetail().fetch(mac_addr, hmac_addr, payload)
        data = res.get('data')[0]
        if data.get('mac'):
            # 有 Mac 表示有数据，否则为 NO DATA
            ret = {
                'route_detail': data,
                'route': route,
                'status': mac_status
            }
            route_detail = {"route_type": data.get("mark")}
        else:
            ret = {'route': route}
            route_detail = {"route_type": "R"}

        # 路由器设备列表按钮
        if flag == "device":
            return JsonResponse(route_detail)

        return render(request, 'system/route_detail.html', ret)

